package com.may.rabbitmq.springbootrabbitmq.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * Created with IntelliJ IDEA.
 *
 * @author nakano_may丶
 * @date 2023/4/11
 * @Version 1.0
 * @description 回调接口
 */
@Component
@Slf4j
public class MyCallBck implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 此注解就是注入的意思，在其他注解完成之后执行！
    @PostConstruct
    public void init() {
        // 注入
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 交换机确认回调的方法
     * 1.发消息 交换机接收到了 回调
     *      1.1 correlationData 保存回调消息的ID及相关信息
     *      1.2 交换机收到消息 ack=true
     *      1.3 cause null
     * 2.发消息交换机接收失败了 回调
     *      2.1 correlationData 保存回调消息的ID及相关信息
     *      2.2 交换机收到消息 ack=false
     *      2.3 cause 失败的原因
     *
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {

        String id = correlationData != null ? correlationData.getId() : "";
        if (ack) {
            log.info("交换机已经收到ID为：{}的消息", id);
        } else {
            log.info("交换机还没有收到id位:{}的消息，原因是：{}", id, cause);
        }
    }

    /**
     * 可以在当消息传递过程中不可达目的地时，将消息返回给生产者
     * 只有不可达目的地的时候，才进行回退
     *
     * @param message
     * @param replyCode
     * @param replyText
     * @param exchange
     * @param routingKey
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.error("消息{},被交换机{}退回,退回原因：{},路由key:{}",
                new String(message.getBody()), exchange, replyCode, routingKey);
    }
}
